# -*- coding:utf-8 -*-

from launch import db
from datetime import datetime
from launch import constants

from werkzeug.security import generate_password_hash, check_password_hash


class BaseModel(object):
    """模型基类，为每个模型补充创建时间与更新时间"""

    create_time = db.Column(db.DateTime, default=datetime.now(), comment='创建时间')
    update_time = db.Column(db.DateTime, default=datetime.now(), onupdate=datetime.now(), comment='更新时间')


class User(BaseModel, db.Model):
    """用户"""
    __tablename__ = "ihome_user_profile"
    __table_args__ = ({'comment': '用户'})

    id = db.Column(db.Integer, primary_key=True, comment='用户编号')
    name = db.Column(db.String(32), unique=True, nullable=False, comment='用户昵称')
    password_hash = db.Column(db.String(128), nullable=False, comment='加密的密码')
    mobile = db.Column(db.String(11), unique=True, nullable=False, comment='手机号')
    real_name = db.Column(db.String(32), comment='真实姓名')
    id_card = db.Column(db.String(32), comment='身份证号')
    avatar_url = db.Column(db.String(128), comment='用户头像路径')
    houses = db.relationship('House', backref="user")  # 用户发布的房屋
    orders = db.relationship("Order", backref="user")  # 用户下的订单

    # 加上property装饰器会把函数变为属性，属性名即函数名
    @property
    def password(self):
        """获取password属性时被调用"""
        # 函数的返回值会作为属性值
        # return "xxx"
        raise AttributeError('不可读')

    # 使用这个装饰器，对应设置属性操作
    @password.setter
    def password(self, origin_password):
        """
        设置password属性时被调用，设置密码加密
        :param origin_password:
        :return:
        """
        self.password_hash = generate_password_hash(origin_password)

    def check_password(self, passwd):
        """
        检查密码的正确性
        :param passwd:
        :return:
        """
        return check_password_hash(self.password_hash, passwd)

    def to_dict(self):
        """将对象转换为字典数据"""
        user_dict = {
            "user_id": self.id,
            "name": self.name,
            "mobile": self.mobile,
            "avatar_url": constants.QINIU_URL_DOMAIN + self.avatar_url if self.avatar_url else "",
            "create_time": self.create_time.strftime("%Y-%m-%d %H:%M:%S")
        }
        return user_dict

    def auth_to_dict(self):
        """将实名信息转换为字典数据"""
        auth_dict = {
            "user_id": self.id,
            "real_name": self.real_name,
            "id_card": self.id_card
        }
        return auth_dict


class Area(BaseModel, db.Model):
    """城区"""
    __tablename__ = "ihome_area_info"
    __table_args__ = ({'comment': '城区'})

    id = db.Column(db.Integer, primary_key=True, comment="区域编号")
    name = db.Column(db.String(32), nullable=False, comment="区域名字")
    houses = db.relationship("House", backref="area")  # 区域的房屋

    def to_dict(self):
        """将对象转换为字典数据"""
        area_dict = {
            "aid": self.id,
            "aname": self.name
        }
        return area_dict


house_facility = db.Table(
    "ihome_house_facility",
    db.Column("house_id", db.Integer, db.ForeignKey("ihome_house_info.id"), primary_key=True, comment="房屋编号"),
    db.Column("facility_id", db.Integer, db.ForeignKey("ihome_facility_info.id"), primary_key=True, comment="设施编号"),
)
# .comment = "房屋设施关系表"
house_facility.comment = "房屋设施关系表"


class House(BaseModel, db.Model):
    """房屋信息"""
    __tablename__ = "ihome_house_info"
    id = db.Column(db.Integer, primary_key=True, comment="房屋编号")
    user_id = db.Column(db.Integer, db.ForeignKey("ihome_user_profile.id"), nullable=False, comment="房屋主人的用户编号")
    area_id = db.Column(db.Integer, db.ForeignKey("ihome_area_info.id"), nullable=False, comment="归属地的区域编号")
    title = db.Column(db.String(64), nullable=False, comment="标题")
    price = db.Column(db.Integer, default=0, comment="单价：单位：元")
    address = db.Column(db.String(512), default="", comment="地址")
    room_count = db.Column(db.Integer, default=1, comment="房间数目")
    acreage = db.Column(db.Integer, default=0, comment="房间面积")
    unit = db.Column(db.String(32), default="", comment="房屋单元，如几室几厅")
    capacity = db.Column(db.Integer, default=1, comment="房间容纳的人数")
    beds = db.Column(db.String(64), default="", comment="房屋床铺的配置")
    deposit = db.Column(db.Integer, default=0, comment="房屋押金")
    min_days = db.Column(db.Integer, default=1, comment="最少入住天数")
    max_days = db.Column(db.Integer, default=0, comment="最多入住天数，0表示不限制")
    order_count = db.Column(db.Integer, default=0, comment="预定完成的该房屋的订单数")
    index_image_url = db.Column(db.String(256), default="", comment="房屋主图片的路径")
    facilities = db.relationship("Facility", secondary=house_facility, backref="houses")  # 房屋的设施
    images = db.relationship("HouseImage", backref="house")  # 房屋的图片
    orders = db.relationship("Order", backref="house")  # 房屋的订单
    # __table_args__ = (Index('index(zone,status)', 'resource_zone', 'resource_status'), {'comment': '压测资源表'})  # 添加索引和表注释
    __table_args__ = ({'comment': '房屋'})

    def to_basic_dict(self):
        """将基本信息转换为字典数据"""
        house_dict = {
            "house_id": self.id,
            "title": self.title,
            "price": self.price,
            "area_name": self.area.name,
            "img_url": constants.QINIU_URL_DOMAIN + self.index_image_url if self.index_image_url else "",
            "room_count": self.room_count,
            "order_count": self.order_count,
            "address": self.address,
            "user_avatar": constants.QINIU_URL_DOMAIN + self.user.avatar_url if self.user.avatar_url else "",
            "ctime": self.create_time.strftime("%Y-%m-%d")
        }
        return house_dict

    def to_full_dict(self):
        """将详细信息转换为字段数据"""
        house_dict = {
            "hid": self.id,
            "user_id": self.user_id,
            "user_name": self.user.name,
            "user_avatar": constants.QINIU_URL_DOMAIN + self.user.avatar_url if self.user.avatar_url else "",
            "title": self.title,
            "price": self.price,
            "address": self.address,
            "room_count": self.room_count,
            "acreage": self.acreage,
            "unit": self.unit,
            "capacity": self.capacity,
            "beds": self.beds,
            "deposit": self.deposit,
            "min_days": self.min_days,
            "max_days": self.max_days
        }
        # 房屋图片
        img_urls = []
        for image in self.images:
            img_urls.append(constants.QINIU_URL_DOMAIN + image.url)
        house_dict["img_urls"] = img_urls

        # 房屋设施
        facilities = []
        for facility in self.facilities:
            facilities.append(facility.id)
        house_dict["facilities"] = facilities
        # 评论信息
        comments = []
        orders = Order.query.filter(Order.house_id == self.id, Order.status == "COMPLETE",
                                    Order.comment != None).order_by(Order.update_time.desc()).limit(
            constants.HOUSE_DETAIL_COMMENT_DISPLAY_COUNTS)
        for order in orders:
            comment = {
                "comment": order.comment,  # 评论的内容
                "user_name": order.user.name,  # 发表评论的用户
                "ctime": order.update_time.strftime("%Y-%m-%d %H:%M:%s")  # 评价的时间
            }
            comments.append(comment)
        house_dict["comments"] = comments
        return house_dict


class Facility(BaseModel, db.Model):
    """设施信息"""
    __tablename__ = "ihome_facility_info"
    __table_args__ = ({'comment': '设施'})
    id = db.Column(db.Integer, primary_key=True, comment="设施编号")
    name = db.Column(db.String(32), nullable=False, comment="设施名字")


class HouseImage(BaseModel, db.Model):
    """房屋图片"""
    __tablename__ = "ihome_house_image"
    __table_args__ = ({'comment': '房屋图片'})

    id = db.Column(db.Integer, primary_key=True, comment="房间图片编号")
    house_id = db.Column(db.Integer, db.ForeignKey("ihome_house_info.id"), nullable=False, comment="房屋编号")
    url = db.Column(db.String(256), nullable=False)  # 图片的路径


class Order(BaseModel, db.Model):
    """订单"""
    __tablename__ = "ihome_order_info"
    __table_args__ = ({'comment': '订单'})

    id = db.Column(db.Integer, primary_key=True, comment="订单编号")
    user_id = db.Column(db.Integer, db.ForeignKey("ihome_user_profile.id"), nullable=False, comment="下订单的用户id")
    house_id = db.Column(db.Integer, db.ForeignKey("ihome_house_info.id"), nullable=False, comment="预订的房间编号")
    begin_date = db.Column(db.DateTime, nullable=False, comment="预订的起始时间")
    end_date = db.Column(db.DateTime, nullable=False, comment="预订的结束时间")
    days = db.Column(db.Integer, nullable=False, comment="预订的总天数")
    house_price = db.Column(db.Integer, nullable=False, comment="房屋的单价")
    amount = db.Column(db.Integer, nullable=False, comment="订单的总金额")
    status = db.Column(db.Enum(  # 枚举
        "WAIT_ACCEPT",  # 待接单
        "WAIT_PAYMENT",  # 待支付
        "PAID",  # 已支付
        "WAIT_COMMENT",  # 待评价
        "COMPLETE",  # 已完成
        "CANCELED",  # 已取消
        "REJECTED",  # 已拒单
    ), default="WAIT_ACCEPT", index=True, comment="订单状态")  # 指明在mysql中这个字段建立索引，加快查询速度
    comment = db.Column(db.Text, comment="订单的评论信息或者拒单原因")
    trade_no = db.Column(db.String(128), comment="支付交易编号")

    # db.Index("status_key", status)
    # db.Index("status_trade_no__key", status, trade_no)

    def to_dict(self):
        """将订单信息转换为字典数据"""
        order_dict = {
            "order_id": self.id,
            "title": self.house.title,
            "img_url": constants.QINIU_URL_DOMAIN + self.house.index_image_url if self.house.index_image_url else "",
            "start_date": self.begin_date.strftime("%Y-%m-%d"),
            "end_date": self.end_date.strftime("%Y-%m-%d"),
            "ctime": self.create_time.strftime("%Y-%m-%d %H:%M:%S"),
            "days": self.days,
            "amount": self.amount,
            "status": self.status,
            "comment": self.comment if self.comment else ""
        }
        return order_dict
